package com.raos.example.redis.networkmodel.reactorthread;

import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * 多线程Reactor 模型（高性能I/O设计模式）
 * 多线程 I/O 业务处理器
 *
 * @author raos
 * @emil 991207823@qq.com
 * @date 2021/7/24 21:04
 **/
public class MultiDispatchHandler implements Runnable {

    private SocketChannel channel;

    private Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    public MultiDispatchHandler(SocketChannel channel) {
        this.channel = channel;
    }

    @Override
    public void run() {
        processor();
    }

    /**
     * I/O 处理流程
     */
    private void processor() {
        executor.execute(new ReaderHandler(channel));
    }

    static class ReaderHandler implements Runnable {

        private SocketChannel socketChannel;

        public ReaderHandler(SocketChannel socketChannel) {
            this.socketChannel = socketChannel;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + ":-----");
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int len = 0, total = 0;
            String msg = "";
            try {
                do {
                    len = socketChannel.read(buffer);
                    if (len > 0) {
                        total += len;
                        msg += new String(buffer.array());
                    }
                } while (len > buffer.capacity());
                System.out.println("total:" + total);

                // msg=表示通信传输报文
                // 耗时2s
                // 登录： username:password
                // ServetRequets: 请求信息
                // 数据库的判断
                // 返回数据，通过channel写回到客户端
                System.out.println(socketChannel.getRemoteAddress() + ": Server receive Msg:" + msg);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                socketChannel = null;
//                try {
//                    socketChannel.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
            }
        }
    }

}
